﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wintellect.PowerCollections;

namespace BullsAndCows
{
    class Program
    {
        public static Random randomObj = new Random();
        public static Random randomPos = new Random();
        public static int position = randomPos.Next(4);
        public static int numberOfGuesses = 0;
        public static string winnerName = "";
        public static bool usedHelp = false;
        public static OrderedMultiDictionary<int, string> scoreboard = new OrderedMultiDictionary<int, string>(false);
        public static StringBuilder reveals = new StringBuilder("xxxx");
        public static int secredNumber = randomObj.Next(10000);
        public static int[] secredNumbers = new int[4];
        public static int bullsNumber = 0;
        public static int cowsNumber = 0;
        public static int number;
        public static void Main(string[] args)
        {
            Console.WriteLine("Welcome to “Bulls and Cows” game. Please try to guess my secret 4-digit number.Use 'top' to view the top scoreboard, 'restart' to start a new game and 'help' to cheat and 'exit' to quit the game.");
            Console.WriteLine(secredNumber);
            while (bullsNumber != 5)
            {
                int tempSecredNumber = secredNumber;
                secredNumbers = new int[4];
                for (int i = 3; i >= 0; i--)
                {
                    secredNumbers[i] = tempSecredNumber % 10;
                    tempSecredNumber = tempSecredNumber / 10;
                }

                Console.WriteLine("Enter a four digit guess:");
                string isNumber = Console.ReadLine();
                if (isNumber == "restart")
                {
                    Restart();
                    continue;
                }
                if (isNumber == "help")
                {
                    Help();
                    continue;
                }
                if (isNumber == "top")
                {
                    PrintTop();
                    continue;
                }
                if (isNumber == "exit")
                {
                    Environment.Exit(1);
                }
                else
                {
                    try
                    {
                        number = int.Parse(isNumber);
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("Invalid input!");
                        continue;
                    }
                    numberOfGuesses++;
                    if (number >= 0 && number < 10000)
                    {
                        int[] myNumbers = new int[4];
                        for (int i = 3; i >= 0; i--)
                        {
                            myNumbers[i] = number % 10;
                            number = number / 10;
                        }
                        for (int i = 0; i < 4; i++)
                        {
                            if (secredNumbers[i] == myNumbers[i])
                            {
                                bullsNumber++;
                                secredNumbers[i] = -1;
                                myNumbers[i] = -2;
                            }
                        }
                        for (int i = 0; i < 4; i++)
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                if (secredNumbers[i] == myNumbers[j] && i != j)
                                {
                                    cowsNumber++;
                                    secredNumbers[i] = -1;
                                    myNumbers[j] = -2;
                                }
                            }
                        }
                        if (bullsNumber != 4)
                        {
                            Console.WriteLine("Wrong number! Bulls:{0}, Cows:{1}", bullsNumber, cowsNumber);
                            bullsNumber = 0;
                            cowsNumber = 0;
                        }
                        else
                        {
                            if (usedHelp == false)
                            {
                                Console.WriteLine("Congratulations! You guessed the secret number in {0} attempts.Please enter your name for the top scoreboard: ", numberOfGuesses);
                                winnerName = Console.ReadLine();
                                scoreboard.Add(numberOfGuesses, winnerName);
                            }
                            else
                            {
                                Console.WriteLine("Congratulations! You guessed the secret number in {0} attempts.", numberOfGuesses);
                            }
                            bullsNumber = 0;
                            cowsNumber = 0;
                            numberOfGuesses = 0;
                            Restart();
                        }
                    }
                    else
                    {
                        Console.WriteLine("The number should be 4 digit number!");
                    }
                }
            }
        }
        public static bool IsXExist(StringBuilder reveals)
        {
            bool exist = false;
            for (int i = 0; i < reveals.Length; i++)
            {
                if (reveals[i] == 'x')
                {
                    exist = true;
                }
            }
            return exist;
        }

        public static void Restart()
        {
            secredNumber = randomObj.Next(10000);
            reveals = new StringBuilder("xxxx");
            usedHelp = false;
            Console.WriteLine("Welcome to “Bulls and Cows” game. Please try to guess my secret 4-digit number.Use 'top' to view the top scoreboard, 'restart' to start a new game and 'help' to cheat and 'exit' to quit the game.");
            Console.WriteLine(secredNumber);
        }

        public static void Help()
        {
            for (int i = 0; i < 4; i++)
            {
                if (i == position)
                {
                    reveals[i] = secredNumbers[position].ToString().ToCharArray()[0];
                }
            }
            Console.WriteLine(reveals);
            do
            {
                position = randomPos.Next(4);
            }
            while (reveals[position] != 'x' && IsXExist(reveals));
            usedHelp = true;
        }

        public static void PrintTop()
        {
            Console.WriteLine("Scoreboard:");
            int i = 1;
            foreach (var item in scoreboard)
            {
                foreach (var innerItem in item.Value)
                {
                    if (i <= 5)
                    {
                        Console.WriteLine("{2}. {0} --> {1} guesses", innerItem, item.Key, i);
                        i = i + 1;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
    }
}
